/**
 * Created by Administrator on 2017/1/15.
 */

var config = require('./config');

var MJ = require('../MJ/MJ');
var MJRoom = require('../MJ/room').MJRoom;

var Const = require('./const');
var SubCode = require('../subCode');

exports.TTMMJRoom = MJRoom.extend({
    HZNUM: 0,
    _passTing: 0,
    NUM1: 0,
    NUM2: 0,
    wait: false,
    _yao: false,
    _fcy: 0,    //飞苍蝇
    _fcyScore: 0,
    _chrckHu: true,
    init: function(rid, creator, msg) {
        this._super(rid, creator, msg);
        this.HZNUM = 0;
        this.NUM1 = 0;
        this.NUM2 = 0;
        this.wait = false;
        this._passTing = 0;
        this._yao = false;
        this._fcy = 0;
        this._fcyScore = 0;
        this._chrckHu = true;
        this.setSaveReplay(true);
    },

    checkInit: function() {
        return this._super();
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/

    getRoomConfig: function() {
        var cfg = this._super();
        cfg.destroyWaitTime = 30;
        cfg.waitTimeoutTime = 90;
        cfg.respDestroyIgnore = 1;
        cfg.MJsettlementWait = 100;
        return cfg;
    },


    getInfo: function() {
        var info = this._super();

        return info;
    },

    getRoundInfo: function() {
        var info = this._super();

        return info;
    },
    getSettlementInfo: function() {
        var info = this._super();
        info.fcy = this._fcy;
        info.fcyScore = this._fcyScore;
        this.enumPlayers(function(eIndex, ePlayer) {
           if (ePlayer.getMark("forceQuit")) {
               info.ForceQuitIndex = eIndex;
           }
        });
        //info.ForceQuitIndex = this._roundForceQuitIndex;
        return info;
    },
    getReconnectInfo: function(rePlayer) {
        var info = this._super(rePlayer);
        info.num1 = this.NUM1;
        info.num2 = this.NUM2;
        info.WAIT = this.wait;
        info.yaoShaiZi = this._yao;

        info.HuangFan = this.HZNUM;
        info.passTing = 5;
        return info;
    },

    onBeforeStartNewRound: function() {
        this._super();
        this._fcyScore = 0;

        this._yao = false;
        this._passTing = 0;
        this._fcy = 0;
    },

    onAfterStartNewRound: function() {
        this._super();
        this.NUM1 = ExNumber.rand(6) + 1;
        this.NUM2 = ExNumber.rand(6) + 1;
        //this.NUM1 = 6;
        //this.NUM2 = 6;
        this.broadcastReplay("onYaoShaiZi", {
            num1: this.NUM1,
            num2: this.NUM2,
        });

        if (this.getOption("HF")) {
            if (this.NUM1 == 4 && this.NUM2 == 4) {
                this.HZNUM += 1;
            } else if (this.NUM1 == 1 && this.NUM2 == 1) {
                this.HZNUM += 1;
            } else if (this.NUM1 == 5 && this.NUM2 == 5) {
                this.HZNUM++;
            } else if (this.NUM1 == 3 && this.NUM2 == 3) {
                this.HZNUM++;
            } else if (this.NUM1 == 2 && this.NUM2 == 2) {
                this.HZNUM++;
            } else if (this.NUM1 == 6 && this.NUM2 == 6) {
                this.HZNUM++;
            }
        }
        this.broadcastReplay("onHuangFan", {
            HuangFan: this.HZNUM,
        });
        //this.preStartPlay();
    },
    onAfterNewCard: function(){
        var player = this.getCurPlayer();
        var hua = player.checkHua();
        if (hua.length > 0) {
            this.onHuaCard(hua);
        }
    },
    preStartPlay: function() {
        this.initPlayersHandCards();

        this.startPlay();

    },

    startPlay: function() {
        var dealer = this.getDealerIndex();

        logger.debug("room=%d sendHangupTask in=TTMMJ.startPlay", this.rid());
        this._sendHangupTask(this._startPlay);
    },

    _startPlay: function() {
        var player = this.getPlayerByIndex(this.getDealerIndex());
        var hua = player.checkHua();
        if (hua.length > 0) {
            this._curPlay = this.getDealerIndex();
            this.onHuaCard(hua);
        }
        this._changeCurPlay(this.getDealerIndex());
        this._doCheckNewCardHangupTask();
    },

    onBeforePlayCard: function(player, msg, card) {
        var code = this._super(player, msg, card);
        if (code) {
            return code;
        }
        /*if(this._curTask == MJ.Task.CHI){
            if(card == player._chiCards[player._chiCards.length - 1].card){
                return SubCode.MJ_PLAY_FAILED;
            }
        }*/
        if (player.isBaoTing() && card != player.getLastCard()) { //天听不能换牌
            return SubCode.MJ_IS_BAOTING;
        }
    },
    onAfterPlayCard: function(player, card, playInfo) {
        if(this._passTing > 4){
            this._passTing = 0;
        }
        if(this._passTing){
            this._passTing++;
        }

    },

    checkCurPlayHangupTask: function() {
        var player = this.getCurPlayer();
        this.onAfterNewCard();
        if (!player.isBaoTing()) {
            var gangArray = player.checkGang();
            if (gangArray.length > 0) {
                this._hangupTask.addGangTask(player.getIndex(), gangArray);
            }
        }

    },

    checkNewCardHangupTask: function() {
        var player = this.getCurPlayer();
        if (player.isBaoTing() ){
            var huIndexs = [];
            var huPattern = player.checkHu();
            if (huPattern != Const.Pattern.NONE) {
                var rules = [];
                if (this.getCurGang()) {
                    rules.push(Const.ScoreRule.GSH);
                }

                var card = player.getLastCard() || player.getInitLastCard();
                this._hangupTask.addHuTask(player.getIndex(), card, player.getIndex(), huPattern, rules);
                huIndexs.push(player.getIndex());
            }


            huIndexs.forEach(function (eIndex) {
                var ePlayer = this.getPlayerByIndex(eIndex);
                if (ePlayer && ePlayer.isBaoTing() && this._chrckHu) {
                    this._hangupTask.submitTask(eIndex, MJ.Task.HU);
                }
            }.bind(this));
        }
        var gangArray = player.checkGang();
        if (gangArray.length > 0) {
            //this._hangupTask.addGangTask(player.getIndex(), gangArray);
            if (player.isBaoTing()) {
                if (!player.checkTingChangeIfGangInTTM(gangArray[0])) {
                    //gangTask.push(gangArray[0]);
                    this._hangupTask.addGangTask(player.getIndex(), gangArray);
                }
            } else {
                this._hangupTask.addGangTask(player.getIndex(), gangArray);
            }

        }
    },

    checkPlayCardHangupTask: function(card) {
        var player = this.getCurPlayer();
        this._checkPlayCardHangupTask(card);
    },

    _checkPlayCardHangupTask: function(card) {
        var curPlay = this.getCurPlay();
        var nextIndex = this.getNextIndex(curPlay);

        var curPlayer = this.getCurPlayer();
        if (!curPlayer.getLastCard() || curPlayer.getLastCard() != card) { // 不是打的上次摸的牌，则重新检查听牌
            var tings = curPlayer.checkTing();
            curPlayer.setTingCards(tings);
        }

        var huIndexs = [];
        this.enumPlayers(function(eIndex, ePlayer) {

            if (eIndex != curPlay && !ePlayer.isRoundHu()) {
                if (!ePlayer.isPassHu() && ePlayer.getBaoTingPassHuTimes() < 1) {
                    if (ePlayer.isBaoTing()) {
                        var huCondition = true;
                        var huPattern = ePlayer.checkHuWithCard(card);
                        /*if (!ePlayer.checkHuCondition(card) && ePlayer.getCurFan() == 0) {
                            if (huPattern <= Const.Pattern.NORMAL) {
                                huCondition = false;
                            }
                        }*/
                        if (huPattern != Const.Pattern.NONE && huCondition) {
                            var rules = [];
                            this._hangupTask.addHuTask(ePlayer.getIndex(), card, curPlay, huPattern, rules);
                            huIndexs.push(eIndex);
                        }
                    }
                }

                if (ePlayer.checkGangWithCard(card)) {
                    //var gangTask = {card: card, from: curPlay, gang: MJ.Gang.DIAN};
                    if (!ePlayer.isBaoTing() || !ePlayer.checkTingChangeIfGangInTTM({card: card, from: curPlay, gang: MJ.Gang.DIAN})){
                        //this._hangupTask.addGangTask(eIndex, gangTask);
                        this._hangupTask.addGangTask(eIndex, [{card: card, from: curPlay, gang: MJ.Gang.DIAN}]);
                    }
                }

                if (!ePlayer.isBaoTing()) {
                    if (ePlayer.checkPengWithCard(card)) {
                        this._hangupTask.addPengTask(eIndex, card, curPlay);
                    }
                    if (eIndex == nextIndex && this.getOption("CP")) { // 下家可以吃牌
                        var maxCards = ePlayer.checkChiWithCard(card);
                        if (maxCards) {
                            this._hangupTask.addChiTask(eIndex, card, curPlay, maxCards);
                        }
                    }
                }
            }
        }.bind(this));

        huIndexs.forEach(function(eIndex) {
            var ePlayer = this.getPlayerByIndex(eIndex);
            if (ePlayer && ePlayer.isBaoTing()) {
                this._hangupTask.submitTask(eIndex, MJ.Task.HU);
            }
        }.bind(this));
    },

    checkGangHangupTask: function(playerIndex, gangInfo) {
        var card = gangInfo.card;
        if (gangInfo.type) {
            card = gangInfo.buCard;
        }

        var huIndexs = [];
        this.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != playerIndex && !ePlayer.isRoundHu() && !ePlayer.isPassHu() && ePlayer.getBaoTingPassHuTimes() < 1) {
                if (ePlayer.isBaoTing()) {
                    var huPattern = ePlayer.checkHuWithCard(card);
                    if (huPattern != Const.Pattern.NONE) { // 抢杠
                        var rules = [];
                        rules.push(Const.ScoreRule.QG);
                        this._hangupTask.addHuTask(eIndex, card, playerIndex, huPattern, rules);
                        huIndexs.push(eIndex);
                    }
                }
            }
        }.bind(this));
    },

    checkGangTaskQG: function(task, gangInfo) {
        return gangInfo.gang == MJ.Gang.BA;
    },

    checkGangNewCard: function(gangInfo) {
        if (gangInfo.type) {
            if (gangInfo.buCard) {
                return true;
            }
        }
        return true;
    },

    checkHuSettlement: function() {
        return true;
    },
    checkStartNewRound: function() {
        if(this.getOnlinePlayerCount() >= this.getMaxPlayer()) {
            this.wait = true;
        }
        return this._super();
    },
    onSettlementHuTask: function(task) {
        var playerIndex = task.playerIndex;
        var pattern = task.pattern;
        var card = task.card;
        var from = task.from;
        var rules = task.rules;
        var huPlayer = this.getPlayerByIndex(playerIndex);
        var room = this;
        var isZM = (playerIndex == from); // 是否是自摸
        var player = this.getPlayerByIndex(playerIndex);

        //var pattern = player._stat.roundPattern;
        var targetsIndex = [];
        var targets = [];

        if (isZM) {
            this.enumPlayers(function (eIndex, ePlayer) {
                if (eIndex != playerIndex && !ePlayer.isRoundHu()) {
                    targetsIndex.push(eIndex);
                    targets.push(ePlayer);
                }
            });
        } else {
            huPlayer.addRoundItemScores(Const.ScoreRule.DH, Const.ItemScore[Const.ScoreRule.DH]);
            targetsIndex.push(from);
            targets.push(this.getPlayerByIndex(from));
            var dpplayer = this.getPlayerByIndex(from);
            dpplayer.isDianPao = true;
        }
        for (var i = 0; i < rules.length; ++i) {
            var rule = rules[i];
            switch (rule) {
                case Const.ScoreRule.QG:
                    if (!isZM) {
                        var targetPlayer = targets[0];
                        if (targetPlayer.getIndex() == this.getCurPlay() && this.getCurGang() > 0) { // 抢杠的被抢玩家一定是当前玩家
                            //targetPlayer.setRoundRule(rule);
                            targetPlayer.cancelLastGangForQG(card);
                        }
                    }
                    break;
                case Const.ScoreRule.GSP:
                    if (!isZM) {
                        var targetPlayer = targets[0];
                        targetPlayer.setLastGangUnscored();
                    }
                    break;
                default:
                    break;
            }
            if(rule == Const.ScoreRule.QG){
                pattern = Const.Pattern.QG;
            }else {
                huPlayer.setRoundRule(rule);
                //huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
            }
        }
        if (isZM) {

            if(pattern == MJ.Pattern.PAIR){
                var rule = Const.ScoreRule.PAIR;
                huPlayer.setRoundRule(rule);
                //huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                if(huPlayer.getHandCardNum() <= 2){
                    rule = Const.ScoreRule.SINGLE;
                    huPlayer.setRoundRule(rule);
                    //huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                }
            }else if(pattern == MJ.Pattern.SINGLE){
                var rule = Const.ScoreRule.SINGLE;
                huPlayer.setRoundRule(rule);
                //huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);

            }else if(pattern == MJ.Pattern.PAIR7){
                var rule = Const.ScoreRule.PAIR7;
                huPlayer.setRoundRule(rule);
                //huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
            }
            pattern = Const.Pattern.ZM;
        }else if(pattern != Const.Pattern.QG){
            if(pattern == MJ.Pattern.PAIR){
                var rule = Const.ScoreRule.PAIR;
                huPlayer.setRoundRule(rule);
                //huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                if(huPlayer.getHandCardNum() <= 2){
                    rule = Const.ScoreRule.SINGLE;
                    huPlayer.setRoundRule(rule);
                    //huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                }
            }else if(pattern == MJ.Pattern.SINGLE){
                var rule = Const.ScoreRule.SINGLE;
                huPlayer.setRoundRule(rule);
                //huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);

            } else if(pattern == MJ.Pattern.PAIR7){
                var rule = Const.ScoreRule.PAIR7;
                huPlayer.setRoundRule(rule);
                //.addRoundItemScores(rule, Const.ItemScore[rule]);
            }
            pattern = Const.Pattern.NORMAL;

        }

        var patternScore = Const.PatternScore[pattern];
        var huResult = isZM ? MJ.Result.ZM : MJ.Result.DH;

        huPlayer.setRoundResult(huResult, targetsIndex, card);
        huPlayer.setRoundPattern(pattern, patternScore);
        var msg = {
            playerIndex: playerIndex,
            card: card,
            from: from,
        };
        if(room.getOption("FCY")){
            var publicCards = room.getPublicCards();
            var cards = publicCards.cards;
            var cangYing = cards[cards.length - 1];
            if(publicCards.isEmpty()){
                cangYing = 0;
            }
            if(cangYing){
                var fScore = 0;
                var subConfig = room.getSubConfig();

                if(MJ.getColor(cangYing) == MJ.Color.HUA || MJ.getColor(cangYing) == MJ.Color.ZI){
                    fScore = 5 * subConfig.options.HUA;
                }else {
                    fScore = MJ.getPoint(cangYing) * subConfig.options.HUA;
                }
                msg.fcy = cangYing;
                msg.fcyScore = fScore;
                room._fcy = cangYing;
                room._fcyScore = fScore;
                player._fcy = cangYing;
                player._fcyScore = fScore;
            }
        }
        this.broadcastReplay("onPlayerHu", msg);
    },
    onHuaCard: function(huaCards){
        var player = this.getCurPlayer();
        player.playHua(huaCards);
        var cards = [];

        for(var i = 0; i < huaCards.length; i++){
            if(this._publicCards.isEmpty()){
               break;
            }
            var card = this._publicCards.getCard();
            cards.push(card);
            player.addNewCard(card);
        }
        player.setPassHu(false);
        this._curTask = 0;
        this._sendPublicCardChanged();

        this._hangupTask.reset();
        this._chrckHu = false;
        this.checkNewCardHangupTask();
        this._chrckHu = true;
        var curTask = false;
        if (this._hangupTask.existUncommitted(player.getIndex())) {
            curTask = true;
        }
        this.broadcastReplay("onPlayHua", {
            playerIndex: player.getIndex(),
            cards: huaCards,
            newCards: cards,
            existHangup: curTask
        });
        this._curGang++;
        if(this._publicCards.isEmpty()){
            this.settlementCurRound(0);
            return;
        }
        var hua = player.checkHua();
        if(hua.length > 0){
            this.onHuaCard(hua);
        }else{
            this._doCheckNewCardHangupTask();
            this.onAfterNewCard()
        }
    },
    onSettlement: function() {
        this.enumPlayers(function (eIndex, ePlayer) {
            ePlayer.settlementGangScore();
        }.bind(this));

        this.enumPlayers(function (eIndex, ePlayer) {

            ePlayer.settlementRules();
        }.bind(this));

        this.enumPlayers(function (eIndex, ePlayer) {
            ePlayer.settlementPatternScore();
        }.bind(this));
    },

    onCurRoundFinished: function() {
        this._super();
        // 计算新的庄家
        if(this._huTasks.length > 1){
            this._dealerIndex = this.getFirstDPIndex();
        }else {
            if (this.getFirstHuPlayerIndex() == this._dealerIndex) {
                this._dealerLZ++;
            } else {
                if(this.getFirstHuPlayerIndex()){
                    this._dealerIndex = this.getFirstHuPlayerIndex();
                }
                this._dealerLZ = 1;
            }
        }

        if (this.isRoundHZ()) {
            this.HZNUM += 1;
        }else if(this.HZNUM){
            this.HZNUM -= 1;
        }

        this.broadcastReplay("onDealerChanged", {
            dealer: this._dealerIndex,
            dealerLZ: this._dealerLZ
        });
        this.broadcastReplay("onHuangFan", {
            HuangFan: this.HZNUM,
        });
    },

    /******************************************************************
     * 消息处理
     ******************************************************************/

    handleGmGetPublicCards: function(player, msg, callback) {
        if (!player.isSuperGM()) {
            callback({code: Code.GM_LEVEL_LIMIT}); return;
        }
        //player.leave = !player.leave;
        callback({"cards": this._publicCards.getRemainCards()});
    },
    handleGmSetPublicCards: function(player, msg, callback) {
        if (!player.isSuperGM()) {
            callback({code: Code.GM_LEVEL_LIMIT}); return;
        }
        //player.leave = !player.leave;

        this._publicCards.setRemainCards(msg.cards);
        callback({});
    },
    handleYaoIsEnd: function(player, msg, callback) {
        callback({});
        if(!this._yao){
            this._yao = true;
            this.preStartPlay();

        }

    },
    /******************************************************************
     * 功能接口
     ******************************************************************/

    /**
     * 结算玩家是否听牌
     * @param player
     * @private
     */
    _settlementPlayerTing: function(player) {
        //已听牌玩家不用再检测
        if (player.isRoundTing()) {
            return;
        }

        // 对未胡牌的玩家检查是否听牌
        var tings = player.checkTing();
        var pattern = Const.Pattern.NONE;
        var patternScore = 0;
        for (var i = 0; i < tings.length; ++i) {
            var ting = tings[i];
            var score = Const.PatternScore[ting.pattern];
            if (score > patternScore) {
                pattern = ting.pattern;
                patternScore = score;
            }
        }

        player.setRoundPattern(pattern, 0);
    },
});